#pragma once 

#include "base.h"
#include <functional>

namespace helper {
namespace demo {

template<typename K, typename V>
class Iterator {
public:
  using key_type = K;
  using value_type = V;
  using pair_type = std::pair<const key_type &, const value_type &>;

  virtual ~Iterator() {}

  virtual pair_type current() const = 0;
  virtual void next() = 0;
  virtual bool hasNext() const = 0;
};

template<typename K = Slice , typename V = Slice>
class ITable {
public:
  using key_type = K;
  using value_type = V;
  using visitor = std::function<bool (const key_type &, const value_type &)>;
  using iterator = Iterator<key_type, value_type>;

  virtual ~ITable() {}

  virtual Status put(const key_type & key, const value_type & value) = 0;
  virtual Status get(const key_type & key, std::string & value) const = 0;
  virtual Status del(const key_type & key) = 0;
  virtual bool foreach(const visitor & v, const key_type & start, const key_type & end) const = 0;
  virtual iterator * range(const key_type& start, const key_type& end) const = 0;


  virtual Status put(const WriteOptions & write, const key_type & key, const value_type & value) = 0;
  virtual Status get(const ReadOptions & read, const key_type & key, std::string & value) const = 0;
  virtual Status del(const WriteOptions & write, const key_type & key) = 0;
  virtual bool foreach(const ReadOptions& read, const visitor & v, const key_type& start, const key_type & end) const = 0;

  virtual iterator * range(const ReadOptions & read, const key_type& start, const key_type& end) const = 0;
};

}//namespace demo 
}//namespace helper
